【AWS CDK】VPC コンストラクタでまとめて作成したサブネットの CIDR ブロックでセキュリティグループの設定をする方法
はじめに
AWS CDK で作成したサブネットの情報をどうやって取得するかハマったときのメモになります。
使用する言語は TypeScript です。
※ この記事は AWS CDK v1.63.0 のものです。 v1.64.0 以降は後述の方法で解決できます。
AWS CDK + TypeScript はいいぞ!
やること
- VPC を作成し、パブリックサブネットを2つ、プライベートサブネットを1つ作成する
- セキュリティグループを作成し、2つ目のパブリックサブネットから5432ポートへの通信を許可する
できたもの
import * as cdk from "@aws-cdk/core"; import * as ec2 from "@aws-cdk/aws-ec2"; import { CfnSubnet, Peer, Port, SecurityGroup } from "@aws-cdk/aws-ec2"; export class ExampleVpcSubnetStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, "VPC", { cidr: "192.168.0.0/16", subnetConfiguration: [ { cidrMask: 24, name: "public-1", subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: "public-2", subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: "private", subnetType: ec2.SubnetType.PRIVATE, }, ], }); const securityGroup = new SecurityGroup(this, "SecurityGroup", { vpc: vpc, }); vpc.selectSubnets({ subnetGroupName: "public-2" }).subnets.forEach((x) => { const cfnSubnet = x.node.defaultChild as CfnSubnet; securityGroup.addIngressRule( Peer.ipv4(cfnSubnet.cidrBlock), Port.tcp(5432) ); }); } }
解説
VPC とサブネットをまとめて作成
Vpc コンストラクタで subnetConfiguration
を使用することでサブネットまでまとめて作成できます。
const vpc = new ec2.Vpc(this, "VPC", { cidr: "192.168.0.0/16", subnetConfiguration: [ { cidrMask: 24, name: "public-1", subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: "public-2", subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: "private", subnetType: ec2.SubnetType.PRIVATE, }, ], });
セキュリティグループの作成
ここは普通にセキュリティグループを作成しているだけです。
const securityGroup = new SecurityGroup(this, "SecurityGroup", { vpc: vpc, });
特定サブネットの CIDER ブロックを取得しセキュリティグループ設定
VPCコンストラクタで作成したサブネットの CIDR ブロックをどうやって取得したらいいのかハマったところで今回のメインになります。
selectSubnets()
で サブネット名を元に特定のサブネットを取得すること自体は IntelliSense のおかげですんなり実装できました。しかし戻り値が ISubnet インタフェースで、それを継承している PublicSubnet クラスにも CIDR ブロックを取得するためのプロパティやメソッドはありませんでした(過去形)
以下のように CfnSubnet
でキャストすることで CIDR ブロックを取り出すことができました。
vpc.selectSubnets({ subnetGroupName: "public-2" }).subnets.forEach((x) => { const cfnSubnet = x.node.defaultChild as CfnSubnet; securityGroup.addIngressRule( Peer.ipv4(cfnSubnet.cidrBlock), Port.tcp(5432) ); });
(v1.64.0以降)と、思っていたら
この記事を下書きに寝かせている間にCDKのバージョンが v1.64.0 に上がり、ISubnet インタフェースに ipv4CidrBlock
プロパティが生えました。
よってわざわざキャストする必要もなくなったので以下のように簡潔に記述することができるようになりました。
vpc.selectSubnets({ subnetGroupName: "public-2" }).subnets.forEach((x) => { securityGroup.addIngressRule(Peer.ipv4(x.ipv4CidrBlock), Port.tcp(5432)); });
まとめ
- AWS CDK + TypeScript はいいぞ!
- AWS CDK は進化が早い
- 鉄は熱いうちに打て